﻿using NetJavap.JVM;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NetJavap.AttributeInfos;

namespace NetJavap
{
    public static class Utils
    {
        public static string ToFormattedString(this AccessFlags accFlag)
        {
            return accFlag.ToString().ToLower().Replace("|", "").Replace(",", "");
        }
        public static T GetAttribute<T>(this IWithAttributeMember member) where T : AttributeInfo
        {
            return (T)member.Attributes.FirstOrDefault(m => m is T);
        }
        public static bool IsMethodDefineEquals(this IWithMethodDescriptorMember m1, IWithMethodDescriptorMember m2)
        {
            if (m1.Parameters.Length != m2.Parameters.Length)
            {
                return false;
            }
            return m1.Parameters.SequenceEqual(m2.Parameters);
        }
        public static int RightMove(int value, int pos)
        {

            if (pos != 0)  //移动 0 位时直接返回原值
            {
                int mask = 0x7fffffff;     // int.MaxValue = 0x7FFFFFFF 整数最大值
                value >>= 1;     //第一次做右移，把符号也算上，无符号整数最高位不表示正负但操作数还是有符号的，有符号数右移1位，正数时高位补0，负数时高位补1
                value &= mask;     //和整数最大值进行逻辑与运算，运算后的结果为忽略表示正负值的最高位
                value >>= pos - 1;     //逻辑运算后的值无符号，对无符号的值直接做右移运算，计算剩下的位
            }
            return value;
        }
        public static long RightMove(long value, int pos)
        {

            if (pos != 0)  //移动 0 位时直接返回原值
            {
                int mask = 0x7fffffff;     // int.MaxValue = 0x7FFFFFFF 整数最大值
                value >>= 1;     //第一次做右移，把符号也算上，无符号整数最高位不表示正负但操作数还是有符号的，有符号数右移1位，正数时高位补0，负数时高位补1
                value &= mask;     //和整数最大值进行逻辑与运算，运算后的结果为忽略表示正负值的最高位
                value >>= pos - 1;     //逻辑运算后的值无符号，对无符号的值直接做右移运算，计算剩下的位
            }
            return value;
        }
        public static JavaObject CreateStringInstance(String str)
        {
            JavaClass stringCls = JVMClassLoader.LoadClass("java/lang/String");
            JavaObject javaObj = new JavaObject(stringCls);
            ArrayJavaClass arrCls = ArrayJavaClass.GetArrayClass(10,str.Length);
            ArrayJavaObject charArr = new ArrayJavaObject(arrCls);
            for (int i = 0; i < str.Length; i++)
			{
                charArr.Elements[i] = str[i];
			}
            MethodInfo strInitMethod = stringCls.GetMethod("<init>",new TypeInfo("V",0),new TypeInfo("C",1));
            CodeAttributeInfo codeAttr = strInitMethod.GetAttribute<CodeAttributeInfo>();
            JVMCodeRunner runner = new JVMCodeRunner(codeAttr);
            runner.CurrentStackFrame.LocalVariableTable[1] = charArr;
            runner.CurrentStackFrame.BindInstance = javaObj;
            runner.CurrentStackFrame.LocalVariableTable[0] = javaObj;
            while (!runner.ExecuteSetp()) ;
            return javaObj;
        }
    }
}
